# -*- coding: utf-8 -*-
from IfaceMap import *
from threading import Thread
from time import *
import socket
from PktHandler import isLocal
from xml.parsers.expat import ExpatError
import ethersense
import os

class ThreadXML(Thread):
  def __init__(self,pkthndl,outfile,lock):
      Thread.__init__(self)
      self.pkthandler=pkthndl
      self.outfile=outfile
      self.alive=True
      self.utils=Utils()
      self.unresolved=[];
      self.outfile2='www/utils.xml'
      self.lock=lock
    
  def stop(self):
    self.alive=False
  def run(self):
    try:      
      while 1:
	if self.alive:
	  
	  self.lock.acquire()
	  try:
	    self.ifmap=parse(self.outfile)
	  except ExpatError, m:
	    print "[!] Parsing of", self.outfile, "failed:", m, self.ifmap
	    sleep(2)
	    continue
	  self.lock.release()
	  
	  g=self.garbageCollector()
	  r=self.resolveAddresses()
	  print "[!]",  g, "timeout connections cleaned", r, "hosts resolved" 


	  # Choose real IP when IPlist ARP PING
	  # Kb calculate and update

	  if g>0 or r>0:
	    uid, gid = ethersense.getNormalId()
	    if g>0:
	      self.lock.acquire()
	      f=open(self.outfile,'w+')
	      self.ifmap.export(f, 0)
	      f.close()
	      self.lock.release()
	    if r>0:
	      f=open(self.outfile2,'w+')
	      self.utils.export(f, 0)
	      f.close()

	  sleep(5)

	else:
	  print '[!] EtherSense XMLHandler quitted.'
	  exit(0)
	  
    except (KeyboardInterrupt):
      print '[!] XMLHandler quitting..'
      exit(0)
    #except IOError, (m,v):
      #print 'Error', self.outfile + ':', m
      #exit(1)
      
  def garbageCollector(self):
    newtime=localtime()
    i=0
    
    for conn in self.ifmap.Connection[:]:
      oldtime = strptime(conn.get_LastSeen() , "%d-%m-%y %H:%M:%S")
      time_difference = int(mktime(newtime) - mktime(oldtime))
      if ((conn.get_Status()!="ACTIVE" and conn.get_Status()!="OPENED") and time_difference > 5) or time_difference > 120:
	del self.ifmap.Connection[self.ifmap.Connection.index(conn)]
	i=i+1
    return i
    
  def resolveAddresses(self):
    resolved=self.utils.get_ResolvedHost()
    i=0
    for conn in self.ifmap.Connection[:]:
      #print isLocal(conn.get_IP1())
      #print isLocal(conn.get_IP2())
      
      
      
      
      founded=False;
      resolvedlist=self.utils.get_ResolvedHost()
      for res in resolvedlist[:]:
	if conn.get_IP1()==res.get_IP():
	  hostname=res.Host
	  #print conn.get_IP1(), "gia risolto in ", hostname
	  founded=True;
	  
      for ip in self.unresolved:
	if(ip==conn.get_IP1()):
	  #print conn.get_IP1(), "irrisolvibile"
	  founded=True;  
	  
      if founded==False:
	try:
	  hostname=socket.gethostbyaddr(conn.get_IP1())[0]
	except:
	  #print conn.get_IP1(), "irrisolvibile"
	  self.unresolved.append(conn.get_IP1())
	else:
	  self.utils.add_ResolvedHost(ResolvedHost(IP=conn.get_IP1(),Host=hostname))
	  #print conn.get_IP1(), "risolto in", hostname
	  i=i+1
	
      
      
      founded=False;
      
      resolvedlist=self.utils.get_ResolvedHost()
      for res in resolvedlist[:]:
	if conn.get_IP2()==res.get_IP():
	  hostname=res.Host
	  #print conn.get_IP2(), "gia risolto in ", hostname
	  founded=True;
      
      for ip in self.unresolved:
	if(ip==conn.get_IP2()):
	  #print conn.get_IP2(), "gia irrisolvibile"
	  founded=True;
      
      if not founded:
	try:
	  hostname=socket.gethostbyaddr(conn.get_IP2())[0]
	except:
	  #print conn.get_IP2(), "irrisolvibile"
	  self.unresolved.append(conn.get_IP2())
	else:
	  self.utils.add_ResolvedHost(ResolvedHost(IP=conn.get_IP2(),Host=hostname))
	  #print conn.get_IP2(), "risolto in", hostname
	  i=i+1
	
    return i